package ru.spb.osll.myfit.server.execute;

import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import ru.spb.osll.myfit.client.service.PageExecutingService;
import ru.spb.osll.myfit.common.PageExecutingResult;
import ru.spb.osll.myfit.common.PageExecutingResult.PageExecutingState;
import ru.spb.osll.myfit.server.Configurator;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.apache.log4j.Logger;

import ru.spb.osll.myfit.util.FileHelper;

public class PageExecutingServiceImpl extends RemoteServiceServlet implements
    PageExecutingService {
  private Logger log = Logger.getLogger(PageExecutingServiceImpl.class);

  private static final long serialVersionUID = 3889574505512661341L;

  private HashMap<String, PageExecutor> pageExecutors = new HashMap<String, PageExecutor>();

  protected PageExecutorFactory m_pageExecutorFactory;

  protected ExecutorService m_executorService;

  public PageExecutingServiceImpl() {
    createParams();
  }

  protected void createParams() {
    Configurator configurator = Configurator.getInstance();
    m_pageExecutorFactory = new PageExecutorFactory(configurator, new FileHelper());
    m_executorService = Executors.newCachedThreadPool();
  }

  public PageExecutingResult getExecutingResult(String id) {
    PageExecutor executor = pageExecutors.get(id);
    if (executor == null) {
      return null;
    }

    PageExecutingResult result = executor.getPageExecutingResult();
    if (result.getState() == PageExecutingState.FINISH ||
        result.getState() == PageExecutingState.FAIL) {
      pageExecutors.remove(id);
    }
    return result;
  }

  public PageExecutingResult executePage(final String pagePath) {

    try {
      PageExecutor pageExecutor = m_pageExecutorFactory
          .createPageExecutor(pagePath);
      m_executorService.execute(pageExecutor);

      PageExecutingResult result = pageExecutor.getPageExecutingResult();

      if (result.getState() != PageExecutingState.FINISH &&
          result.getState() != PageExecutingState.FAIL) {
        pageExecutors.put(pageExecutor.getId(), pageExecutor);
      }

      return result;

    } catch (Exception e) {
      log.error("can't execute page: " + pagePath, e);
      PageExecutingResult failResult = new PageExecutingResult();
      failResult.setState(PageExecutingState.FAIL);
      return failResult;
    }

  }
}
